home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1995 January / macformat-020.iso / Shareware City / Developers / OutOfPhase1.01Source / OutOfPhase Folder / SampleStorageActual.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-10-01  |  14.8 KB  |  449 lines  |  [TEXT/KAHL]

  1. /* SampleStorageActual.c */
  2. /*****************************************************************************/
  3. /*                                                                           */
  4. /*    Out Of Phase:  Digital Music Synthesis on General Purpose Computers    */
  5. /*    Copyright (C) 1994  Thomas R. Lawrence                                 */
  6. /*                                                                           */
  7. /*    This program is free software; you can redistribute it and/or modify   */
  8. /*    it under the terms of the GNU General Public License as published by   */
  9. /*    the Free Software Foundation; either version 2 of the License, or      */
  10. /*    (at your option) any later version.                                    */
  11. /*                                                                           */
  12. /*    This program is distributed in the hope that it will be useful,        */
  13. /*    but WITHOUT ANY WARRANTY; without even the implied warranty of         */
  14. /*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          */
  15. /*    GNU General Public License for more details.                           */
  16. /*                                                                           */
  17. /*    You should have received a copy of the GNU General Public License      */
  18. /*    along with this program; if not, write to the Free Software            */
  19. /*    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.              */
  20. /*                                                                           */
  21. /*    Thomas R. Lawrence can be reached at tomlaw@world.std.com.             */
  22. /*                                                                           */
  23. /*****************************************************************************/
  24.  
  25. #include "MiscInfo.h"
  26. #include "Audit.h"
  27. #include "Debug.h"
  28. #include "Definitions.h"
  29.  
  30. #include "SampleStorageActual.h"
  31. #include "Memory.h"
  32.  
  33.  
  34. /* data is stored in the following format: */
  35. /*  - 8bit mono:  packed array of bytes */
  36. /*  - 16bit mono:  packed array of short integers */
  37. /*  - 8bit stereo:  packed array of 2-byte units, the lower == left channel */
  38. /*  - 16bit stereo:  packed array of 2-short int units, the lower == left channel */
  39.  
  40.  
  41. struct SampleStorageActualRec
  42.     {
  43.         char*                                    Buffer;
  44.         NumBitsType                        NumberOfBits;
  45.         NumChannelsType                MonoStereo;
  46.         long                                    NumFrames;
  47.     };
  48.  
  49.  
  50. /* create a new sample storage object, with the array zeroed out */
  51. SampleStorageActualRec*        NewSampleStorageActual(NumBitsType NumBits,
  52.                                                         NumChannelsType NumChannels, long NumSampleFrames)
  53.     {
  54.         SampleStorageActualRec*    Storage;
  55.         long                                        BytesPerFrame;
  56.         long                                        Limit;
  57.         long                                        Scan;
  58.  
  59.         ERROR((NumBits != eSample8bit) && (NumBits != eSample16bit),PRERR(ForceAbort,
  60.             "eSampleStereo:  bad number of bits"));
  61.         ERROR((NumChannels != eSampleMono) && (NumChannels != eSampleStereo),
  62.             PRERR(ForceAbort,"eSampleStereo:  bad number of channels"));
  63.         Storage = (SampleStorageActualRec*)AllocPtrCanFail(sizeof(SampleStorageActualRec),
  64.             "SampleStorageActualRec");
  65.         if (Storage == NIL)
  66.             {
  67.              FailurePoint1:
  68.                 return NIL;
  69.             }
  70.         BytesPerFrame = 1;
  71.         switch (NumBits)
  72.             {
  73.                 default:
  74.                     EXECUTE(PRERR(ForceAbort,"NewSampleStorageActual:  bad num bits"));
  75.                     break;
  76.                 case eSample8bit:
  77.                     break;
  78.                 case eSample16bit:
  79.                     BytesPerFrame = BytesPerFrame * (sizeof(short) / sizeof(char));
  80.                     break;
  81.             }
  82.         switch (NumChannels)
  83.             {
  84.                 default:
  85.                     EXECUTE(PRERR(ForceAbort,"NewSampleStorageActual:  bad num channels"));
  86.                     break;
  87.                 case eSampleMono:
  88.                     break;
  89.                 case eSampleStereo:
  90.                     BytesPerFrame = BytesPerFrame * 2;
  91.                     break;
  92.             }
  93.         Storage->Buffer = AllocPtrCanFail((NumSampleFrames + 1) * BytesPerFrame,
  94.             "SampleArray");
  95.         if (Storage->Buffer == NIL)
  96.             {
  97.              FailurePoint2:
  98.                 ReleasePtr((char*)Storage);
  99.                 goto FailurePoint1;
  100.             }
  101.         Limit = PtrSize(Storage->Buffer);
  102.         for (Scan = 0; Scan < Limit; Scan += 1)
  103.             {
  104.                 Storage->Buffer[Scan] = 0;
  105.             }
  106.         Storage->NumberOfBits = NumBits;
  107.         Storage->MonoStereo = NumChannels;
  108.         Storage->NumFrames = NumSampleFrames;
  109.         return Storage;
  110.     }
  111.  
  112.  
  113. /* dispose of a sample storage object */
  114. void                                            DisposeSampleStorageActual(SampleStorageActualRec* Storage)
  115.     {
  116.         CheckPtrExistence(Storage);
  117.         ReleasePtr(Storage->Buffer);
  118.         ReleasePtr((char*)Storage);
  119.     }
  120.  
  121.  
  122. /* get the number of bits the sample storage object contains */
  123. NumBitsType                                GetSampleStorageActualNumBits(SampleStorageActualRec* Storage)
  124.     {
  125.         CheckPtrExistence(Storage);
  126.         return Storage->NumberOfBits;
  127.     }
  128.  
  129.  
  130. /* get the number of channels the storage object contains */
  131. NumChannelsType                        GetSampleStorageActualNumChannels(
  132.                                                         SampleStorageActualRec* Storage)
  133.     {
  134.         CheckPtrExistence(Storage);
  135.         return Storage->MonoStereo;
  136.     }
  137.  
  138.  
  139. /* get the number of sample frames the object contains */
  140. long                                            GetSampleStorageActualNumFrames(
  141.                                                         SampleStorageActualRec* Storage)
  142.     {
  143.         CheckPtrExistence(Storage);
  144.         return Storage->NumFrames;
  145.     }
  146.  
  147.  
  148. /* get the value of a sample frame */
  149. largefixedsigned                    GetSampleStorageActualValue(SampleStorageActualRec* Storage,
  150.                                                         long Index, ChannelType WhichChannel)
  151.     {
  152.         double                                    Resultant;
  153.  
  154.         CheckPtrExistence(Storage);
  155.         switch (Storage->MonoStereo)
  156.             {
  157.                 default:
  158.                     EXECUTE(PRERR(ForceAbort,
  159.                         "GetSampleStorageActualValue:  bad internal num channels"));
  160.                     break;
  161.                 case eSampleMono:
  162.                     ERROR(WhichChannel != eMonoChannel,PRERR(ForceAbort,
  163.                         "GetSampleStorageActualValue:  invalid channel selector"));
  164.                     switch (Storage->NumberOfBits)
  165.                         {
  166.                             default:
  167.                                 EXECUTE(PRERR(ForceAbort,
  168.                                     "GetSampleStorageActualValue:  bad internal num bits"));
  169.                                 break;
  170.                             case eSample8bit:
  171.                                 PRNGCHK(Storage->Buffer,&(((char*)Storage->Buffer)[Index]),
  172.                                     sizeof(char));
  173.                                 Resultant = ((double)((signed char*)Storage->Buffer)[Index]) / MAX8BIT;
  174.                                 break;
  175.                             case eSample16bit:
  176.                                 PRNGCHK(Storage->Buffer,&(((short*)Storage->Buffer)[Index]),
  177.                                     sizeof(short));
  178.                                 Resultant = ((double)((signed short*)Storage->Buffer)[Index]) / MAX16BIT;
  179.                                 break;
  180.                         }
  181.                     break;
  182.                 case eSampleStereo:
  183.                     switch (Storage->NumberOfBits)
  184.                         {
  185.                             default:
  186.                                 EXECUTE(PRERR(ForceAbort,
  187.                                     "GetSampleStorageActualValue:  bad internal num bits"));
  188.                                 break;
  189.                             case eSample8bit:
  190.                                 switch (WhichChannel)
  191.                                     {
  192.                                         default:
  193.                                             EXECUTE(PRERR(ForceAbort,
  194.                                                 "GetSampleStorageActualValue:  bad channel selector"));
  195.                                             break;
  196.                                         case eLeftChannel:
  197.                                             PRNGCHK(Storage->Buffer,&(((char*)Storage->Buffer)[2 * Index]),
  198.                                                 sizeof(char));
  199.                                             Resultant = ((double)((signed char*)Storage->Buffer)[2 * Index])
  200.                                                 / MAX8BIT;
  201.                                             break;
  202.                                         case eRightChannel:
  203.                                             PRNGCHK(Storage->Buffer,&(((char*)Storage->Buffer)
  204.                                                 [(2 * Index) + 1]),sizeof(char));
  205.                                             Resultant = ((double)((signed char*)Storage->Buffer)[(2 * Index) + 1])
  206.                                                 / MAX8BIT;
  207.                                             break;
  208.                                     }
  209.                                 break;
  210.                             case eSample16bit:
  211.                                 switch (WhichChannel)
  212.                                     {
  213.                                         default:
  214.                                             EXECUTE(PRERR(ForceAbort,
  215.                                                 "GetSampleStorageActualValue:  bad channel selector"));
  216.                                             break;
  217.                                         case eLeftChannel:
  218.                                             PRNGCHK(Storage->Buffer,&(((short*)Storage->Buffer)[2 * Index]),
  219.                                                 sizeof(short));
  220.                                             Resultant = ((double)((signed short*)Storage->Buffer)[2 * Index])
  221.                                                 / MAX8BIT;
  222.                                             break;
  223.                                         case eRightChannel:
  224.                                             PRNGCHK(Storage->Buffer,&(((short*)Storage->Buffer)
  225.                                                 [(2 * Index) + 1]),sizeof(short));
  226.                                             Resultant = ((double)((signed short*)Storage->Buffer)[(2 * Index) + 1])
  227.                                                 / MAX8BIT;
  228.                                             break;
  229.                                     }
  230.                                 break;
  231.                         }
  232.                     break;
  233.             }
  234.         return double2largefixed(Resultant);
  235.     }
  236.  
  237.  
  238. /* change the value of a sample frame */
  239. void                                            SetSampleStorageActualValue(SampleStorageActualRec* Storage,
  240.                                                         long Index, ChannelType WhichChannel,
  241.                                                         largefixedsigned NewValue)
  242.     {
  243.         double                                    TargetValue;
  244.  
  245.         CheckPtrExistence(Storage);
  246.         switch (Storage->MonoStereo)
  247.             {
  248.                 default:
  249.                     EXECUTE(PRERR(ForceAbort,
  250.                         "SetSampleStorageActualValue:  bad internal num channels"));
  251.                     break;
  252.                 case eSampleMono:
  253.                     ERROR(WhichChannel != eMonoChannel,PRERR(ForceAbort,
  254.                         "SetSampleStorageActualValue:  invalid channel selector"));
  255.                     switch (Storage->NumberOfBits)
  256.                         {
  257.                             default:
  258.                                 EXECUTE(PRERR(ForceAbort,
  259.                                     "SetSampleStorageActualValue:  bad internal num bits"));
  260.                                 break;
  261.                             case eSample8bit:
  262.                                 TargetValue = roundtonearest(largefixed2double(NewValue) * MAX8BIT);
  263.                                 if (TargetValue > MAX8BIT)
  264.                                     {
  265.                                         TargetValue = MAX8BIT;
  266.                                     }
  267.                                 else if (TargetValue < MIN8BIT)
  268.                                     {
  269.                                         TargetValue = MIN8BIT;
  270.                                     }
  271.                                 PRNGCHK(Storage->Buffer,&(((char*)Storage->Buffer)[Index]),
  272.                                     sizeof(char));
  273.                                 ((char*)Storage->Buffer)[Index] = TargetValue;
  274.                                 if (Index == Storage->NumFrames - 1)
  275.                                     {
  276.                                         PRNGCHK(Storage->Buffer,&(((char*)Storage->Buffer)
  277.                                             [Storage->NumFrames]),sizeof(char));
  278.                                         ((char*)Storage->Buffer)[Storage->NumFrames] = TargetValue;
  279.                                     }
  280.                                 break;
  281.                             case eSample16bit:
  282.                                 TargetValue = roundtonearest(largefixed2double(NewValue) * MAX16BIT);
  283.                                 if (TargetValue > MAX16BIT)
  284.                                     {
  285.                                         TargetValue = MAX16BIT;
  286.                                     }
  287.                                 else if (TargetValue < MIN16BIT)
  288.                                     {
  289.                                         TargetValue = MIN16BIT;
  290.                                     }
  291.                                 PRNGCHK(Storage->Buffer,&(((short*)Storage->Buffer)[Index]),
  292.                                     sizeof(short));
  293.                                 ((short*)Storage->Buffer)[Index] = TargetValue;
  294.                                 if (Index == Storage->NumFrames - 1)
  295.                                     {
  296.                                         PRNGCHK(Storage->Buffer,&(((short*)Storage->Buffer)
  297.                                             [Storage->NumFrames]),sizeof(short));
  298.                                         ((short*)Storage->Buffer)[Storage->NumFrames - 1] = TargetValue;
  299.                                     }
  300.                                 break;
  301.                         }
  302.                     break;
  303.                 case eSampleStereo:
  304.                     switch (Storage->NumberOfBits)
  305.                         {
  306.                             default:
  307.                                 EXECUTE(PRERR(ForceAbort,
  308.                                     "SetSampleStorageActualValue:  bad internal num bits"));
  309.                                 break;
  310.                             case eSample8bit:
  311.                                 switch (WhichChannel)
  312.                                     {
  313.                                         default:
  314.                                             EXECUTE(PRERR(ForceAbort,
  315.                                                 "SetSampleStorageActualValue:  bad channel selector"));
  316.                                             break;
  317.                                         case eLeftChannel:
  318.                                             TargetValue = roundtonearest(largefixed2double(NewValue) * MAX8BIT);
  319.                                             if (TargetValue > MAX8BIT)
  320.                                                 {
  321.                                                     TargetValue = MAX8BIT;
  322.                                                 }
  323.                                             else if (TargetValue < MIN8BIT)
  324.                                                 {
  325.                                                     TargetValue = MIN8BIT;
  326.                                                 }
  327.                                             PRNGCHK(Storage->Buffer,&(((char*)Storage->Buffer)[2 * Index]),
  328.                                                 sizeof(char));
  329.                                             ((char*)Storage->Buffer)[2 * Index] = TargetValue;
  330.                                             if (Index == Storage->NumFrames - 1)
  331.                                                 {
  332.                                                     PRNGCHK(Storage->Buffer,&(((char*)Storage->Buffer)
  333.                                                         [2 * Storage->NumFrames]),sizeof(char));
  334.                                                     ((char*)Storage->Buffer)[2 * Storage->NumFrames] = TargetValue;
  335.                                                 }
  336.                                             break;
  337.                                         case eRightChannel:
  338.                                             TargetValue = roundtonearest(largefixed2double(NewValue) * MAX8BIT);
  339.                                             if (TargetValue > MAX8BIT)
  340.                                                 {
  341.                                                     TargetValue = MAX8BIT;
  342.                                                 }
  343.                                             else if (TargetValue < MIN8BIT)
  344.                                                 {
  345.                                                     TargetValue = MIN8BIT;
  346.                                                 }
  347.                                             PRNGCHK(Storage->Buffer,&(((char*)Storage->Buffer)
  348.                                                 [(2 * Index) + 1]),sizeof(char));
  349.                                             ((char*)Storage->Buffer)[(2 * Index) + 1] = TargetValue;
  350.                                             if (Index == Storage->NumFrames - 1)
  351.                                                 {
  352.                                                     PRNGCHK(Storage->Buffer,&(((char*)Storage->Buffer)
  353.                                                         [(2 * Storage->NumFrames) + 1]),sizeof(char));
  354.                                                     ((char*)Storage->Buffer)[(2 * Storage->NumFrames) + 1]
  355.                                                         = TargetValue;
  356.                                                 }
  357.                                             break;
  358.                                     }
  359.                                 break;
  360.                             case eSample16bit:
  361.                                 switch (WhichChannel)
  362.                                     {
  363.                                         default:
  364.                                             EXECUTE(PRERR(ForceAbort,
  365.                                                 "SetSampleStorageActualValue:  bad channel selector"));
  366.                                             break;
  367.                                         case eLeftChannel:
  368.                                             TargetValue = roundtonearest(largefixed2double(NewValue) * MAX16BIT);
  369.                                             if (TargetValue > MAX16BIT)
  370.                                                 {
  371.                                                     TargetValue = MAX16BIT;
  372.                                                 }
  373.                                             else if (TargetValue < MIN16BIT)
  374.                                                 {
  375.                                                     TargetValue = MIN16BIT;
  376.                                                 }
  377.                                             PRNGCHK(Storage->Buffer,&(((short*)Storage->Buffer)[2 * Index]),
  378.                                                 sizeof(short));
  379.                                             ((short*)Storage->Buffer)[2 * Index] = TargetValue;
  380.                                             if (Index == Storage->NumFrames - 1)
  381.                                                 {
  382.                                                     PRNGCHK(Storage->Buffer,&(((short*)Storage->Buffer)
  383.                                                         [2 * Storage->NumFrames]),sizeof(short));
  384.                                                     ((short*)Storage->Buffer)[2 * Storage->NumFrames]
  385.                                                         = TargetValue;
  386.                                                 }
  387.                                             break;
  388.                                         case eRightChannel:
  389.                                             TargetValue = roundtonearest(largefixed2double(NewValue) * MAX16BIT);
  390.                                             if (TargetValue > MAX16BIT)
  391.                                                 {
  392.                                                     TargetValue = MAX16BIT;
  393.                                                 }
  394.                                             else if (TargetValue < MIN16BIT)
  395.                                                 {
  396.                                                     TargetValue = MIN16BIT;
  397.                                                 }
  398.                                             PRNGCHK(Storage->Buffer,&(((short*)Storage->Buffer)
  399.                                                 [(2 * Index) + 1]),sizeof(short));
  400.                                             ((short*)Storage->Buffer)[(2 * Index) + 1] = TargetValue;
  401.                                             if (Index == Storage->NumFrames - 1)
  402.                                                 {
  403.                                                     PRNGCHK(Storage->Buffer,&(((short*)Storage->Buffer)
  404.                                                         [(2 * Storage->NumFrames) + 1]),sizeof(short));
  405.                                                     ((short*)Storage->Buffer)[(2 * Storage->NumFrames) + 1]
  406.                                                         = TargetValue;
  407.                                                 }
  408.                                             break;
  409.                                     }
  410.                                 break;
  411.                         }
  412.                     break;
  413.             }
  414.     }
  415.  
  416.  
  417. /* get a reference to the raw data.  The raw data will either be an array of chars */
  418. /* (for 8-bit data) or an array of shorts (for 16-bit data).  There will be */
  419. /* GetSampleStorageActualNumFrames + 1  frames; the extra one at the end is to */
  420. /* make anti-aliasing more efficient, and repeats the second-last word of data */
  421. char*                                            GetSampleStorageActualRawData(SampleStorageActualRec* Storage)
  422.     {
  423.         CheckPtrExistence(Storage);
  424.         return Storage->Buffer;
  425.     }
  426.  
  427.  
  428. /* get a copy of a particular channel of data from the sample */
  429. largefixedsigned*                    SampleStorageActualGetChannelFixed(
  430.                                                         SampleStorageActualRec* Storage, ChannelType WhichChannel)
  431.     {
  432.         largefixedsigned*                Data;
  433.         long                                        Limit;
  434.         long                                        Scan;
  435.  
  436.         CheckPtrExistence(Storage);
  437.         Limit = GetSampleStorageActualNumFrames(Storage);
  438.         Data = (largefixedsigned*)AllocPtrCanFail(sizeof(largefixedsigned)
  439.             * Limit,"SampleFixed");
  440.         if (Data != NIL)
  441.             {
  442.                 for (Scan = 0; Scan < Limit; Scan += 1)
  443.                     {
  444.                         Data[Scan] = GetSampleStorageActualValue(Storage,Scan,WhichChannel);
  445.                     }
  446.             }
  447.         return Data;
  448.     }
  449.